using NUnit.Framework;
using ServiceStack.Common.Tests.Models;
using ServiceStack.DataAnnotations;
using ServiceStack.Text;

namespace ServiceStack.OrmLite.MySql.Tests;

[TestFixture]
public class OrmLiteInsertTests
	: OrmLiteTestBase
{

	[Test]
	public void Can_insert_into_ModelWithFieldsOfDifferentTypes_table()
	{
		using var db = OpenDbConnection();
		db.CreateTable<ModelWithFieldsOfDifferentTypes>(true);

		var row = ModelWithFieldsOfDifferentTypes.Create(1);

		db.Insert(row);
	}

	[Test]
	public void Can_insert_and_select_from_ModelWithFieldsOfDifferentTypes_table()
	{
		using var db = OpenDbConnection();
		db.CreateTable<ModelWithFieldsOfDifferentTypes>(true);

		var row = ModelWithFieldsOfDifferentTypes.Create(1);

		db.Insert(row);

		var rows = db.Select<ModelWithFieldsOfDifferentTypes>();

		Assert.That(rows, Has.Count.EqualTo(1));

		ModelWithFieldsOfDifferentTypes.AssertIsEqual(rows[0], row);
	}

	[Test]
	public void Can_insert_and_select_from_ModelWithFieldsOfNullableTypes_table()
	{
		using var db = OpenDbConnection();
		db.DropAndCreateTable<ModelWithFieldsOfNullableTypes>();
		db.GetLastSql().Print();

		var row = ModelWithFieldsOfNullableTypes.Create(1);

		db.Insert(row);

		var rows = db.Select<ModelWithFieldsOfNullableTypes>();

		Assert.That(rows, Has.Count.EqualTo(1));

		ModelWithFieldsOfNullableTypes.AssertIsEqual(rows[0], row);
	}

	[Test]
	public void Can_insert_and_select_from_ModelWithFieldsOfDifferentAndNullableTypes_table()
	{
		using var db = OpenDbConnection();
		db.DropAndCreateTable<ModelWithFieldsOfDifferentAndNullableTypes>();
		db.GetLastSql().Print();

		var row = ModelWithFieldsOfDifferentAndNullableTypes.Create(1);

		db.Insert(row);

		var rows = db.Select<ModelWithFieldsOfDifferentAndNullableTypes>();

		Assert.That(rows, Has.Count.EqualTo(1));

		ModelWithFieldsOfDifferentAndNullableTypes.AssertIsEqual(rows[0], row);
	}

	[Test]
	public void Can_insert_table_with_null_fields()
	{
		using var db = OpenDbConnection();
		db.CreateTable<ModelWithIdAndName>(true);

		var row = ModelWithIdAndName.Create(1);
		row.Name = null;

		db.Insert(row);

		var rows = db.Select<ModelWithIdAndName>();

		Assert.That(rows, Has.Count.EqualTo(1));

		ModelWithIdAndName.AssertIsEqual(rows[0], row);
	}

	[Test]
	public void Can_retrieve_LastInsertId_from_inserted_table()
	{
		using var db = OpenDbConnection();
		db.CreateTable<ModelWithIdAndName1>(true);

		var row1 = new ModelWithIdAndName1() { Name = "A", Id = 4 };
		var row2 = new ModelWithIdAndName1() { Name = "B", Id = 5 };

		db.Insert(row1);
		var row1LastInsertId = db.LastInsertId();

		db.Insert(row2);
		var row2LastInsertId = db.LastInsertId();

		var insertedRow1 = db.SingleById<ModelWithIdAndName1>(row1LastInsertId);
		var insertedRow2 = db.SingleById<ModelWithIdAndName1>(row2LastInsertId);

		Assert.That(insertedRow1.Name, Is.EqualTo(row1.Name));
		Assert.That(insertedRow2.Name, Is.EqualTo(row2.Name));
	}

	[Test]
	public void Can_insert_TaskQueue_table()
	{
		using var db = OpenDbConnection();
		db.CreateTable<TaskQueue>(true);

		var row = TaskQueue.Create(1);

		db.Insert(row);

		var rows = db.Select<TaskQueue>();

		Assert.That(rows, Has.Count.EqualTo(1));

		//Update the auto-increment id
		row.Id = rows[0].Id;

		TaskQueue.AssertIsEqual(rows[0], row);
	}

}

class ModelWithIdAndName1
{
	[AutoIncrement]
	public int Id { get; set; }
	public string Name { get; set; }
}